<script setup lang="ts">
// 导入封装的组件
import RoomStatus from './RoomStatus.vue';
import RoomMessage from './RoomMessage.vue';
import RoomAction from './RoomAction.vue';
import { io } from 'socket.io-client';
import type { Socket } from 'socket.io-client';
import { onMounted, onUnmounted, ref, nextTick } from 'vue';
import { baseURL } from '@/utils/request';
import { useUserStore } from '@/stores/user';
import { useRoute } from 'vue-router';
import type { Message, TimeMessages } from '@/types/room';
import { MsgType, OrderType } from '@/enums';
import type { ConsultOrderItem } from '@/types/consult';
import { getConsultOrderDetail } from '@/services/consult';
import dayjs from 'dayjs';
import { Toast } from 'vant';

const userStore = useUserStore();
const route = useRoute();
// 连接实例
let socket: Socket;

// 页面显示消息列表
const list = ref<Message[]>([]);

// 1、建立连接
onMounted(() => {
  socket = io(baseURL, {
    // 认证用户
    auth: {
      token: `Bearer ${userStore.user?.token}`,
    },
    query: {
      orderId: route.query.orderId,
    },
  });

  // 2、监听各种通用连接事件
  // 连接建立成功事件
  socket.on('connect', () => {
    console.log('socket连接成功');
    // 再次连接后清空聊天记录
    // 场景：如果离开当前页面很久，websocket可能会断开连接。
    // 再回到当前页面清空列表。
    list.value = [];
  });
  // 连接错误
  socket.on('error', (error) => {
    console.log('socket连接错误', error);
  });
  // 断开连接
  socket.on('disconnect', () => {
    console.log('socket连接断开');
  });

  // 监听业务功能事件
  // socket.on('chatMsgList', (event: Data<TimeMessages[]>) => {
  //   console.log(event);
  //   const data: TimeMessages[] = event.data;
  socket.on('chatMsgList', ({ data }: { data: TimeMessages[] }) => {
    console.log('chatMsgList：', data);
    // 处理数据
    if (data.length > 0) {
      // 一次时间分片数据（分页的1页）
      const timeMessage = data[0];
      // 初始化分片（分段、分页）时间
      time.value = timeMessage.createTime;
      // 处理列表
      const messageList: Message[] = [];
      messageList.push({
        id: timeMessage.createTime,
        msgType: MsgType.Notify,
        createTime: timeMessage.createTime,
        msg: {
          content: timeMessage.createTime,
        },
      });
      messageList.push(...timeMessage.items);
      // 每次的消息数据，追加到当前页面
      list.value.unshift(...messageList);
      console.log('查看list数据', list.value);
      // 设置下拉刷新状态为false
      loading.value = false;
      // 设置滚动条
      nextTick(() => {
        if (firstLoadMsg.value) {
          // 设置消息已读
          socket.emit(
            'updateMsgStatus',
            messageList[messageList.length - 1].id
          );
          window.scrollTo(0, document.body.scrollHeight);
          firstLoadMsg.value = false;
        }
      });
    } else {
      // 没有更多数据
      loading.value = false;
      Toast('没有更多聊天记录了');
    }
  });

  // 监听订单状态变化
  socket.on('statusChange', (statusChangeData) => {
    console.log('========', statusChangeData);
    if (consult.value) {
      consult.value.status = statusChangeData.status;
    }
    // 重新获取订单详情订单详情
    // const data = await getConsultOrderDetail(route.query.orderId as string);
  });

  // 接收消息事件
  socket.on('receiveChatMsg', (data: Message) => {
    console.log('从服务器端接收到的数据', data.msg);
    // 将消息push到列表数据容器 list
    list.value.push(data);
    // 设置消息已读
    socket.emit('updateMsgStatus', data.id);
    // 放到下一个nextTick是vue更新完之后的操作
    // await nextTick();
    // 第二种写法
    nextTick(() => {
      // 把窗口滚动到最底部
      window.scrollTo(0, document.body.scrollHeight);
      // 或者 scrollTo 的第二个参数指定一个非常大的值（最大就是 number 类型可取值的最大）
      // https://blog.csdn.net/sssuuuunnn/article/details/120329166
      // window.scrollTo(0, 9007199254740991);
    });
  });
});
// 3、关闭连接
onUnmounted(() => {
  socket.close();
});

// 订单详情
const consult = ref<ConsultOrderItem>();
// 组件mounted后请求订单详情
onMounted(async () => {
  const data = await getConsultOrderDetail(route.query.orderId as string);
  consult.value = data;
  console.log('订单详情', data);
});

// 发送文字消息给到服务器
const sendText = (text: string) => {
  console.log('子组件传递的', text);
  // 发送消息到服务器
  socket.emit('sendChatMsg', {
    from: userStore.user?.id, // 发送人
    to: consult.value?.docInfo?.id, // 发送给谁（接收人）
    msgType: MsgType.MsgText,
    msg: {
      content: text,
    },
  });
};

// 发送图片消息到服务器
const sendImage = (img: { id: string; url: string }) => {
  console.log('子组件传递的', img);
  // 发送消息到服务器
  socket.emit('sendChatMsg', {
    from: userStore.user?.id, // 发送人
    to: consult.value?.docInfo?.id, // 发送给谁（接收人）
    msgType: MsgType.MsgImage,
    msg: {
      picture: img,
    },
  });
};

// 下拉刷新组件配置使用
const loading = ref(false);
// 时间分片的定义
const time = ref('');
// 是否第一次加载聊天记录
const firstLoadMsg = ref(true);
const onRefresh = () => {
  socket.emit('getChatMsgList', 20, time.value, route.query.orderId);
};
</script>
<template>
  <div class="room">
    <CpNavBar title="问诊室" />
    <!-- 组合封装的组件 -->
    <RoomStatus :status="consult?.status" :countdown="consult?.countdown" />
    <van-pull-refresh v-model="loading" @refresh="onRefresh">
      <RoomMessage :list="list" />
    </van-pull-refresh>
    <RoomAction
      :disabled="consult?.status !== OrderType.ConsultChat"
      @send-text="sendText"
      @send-image="sendImage"
    />
  </div>
</template>
<style lang="scss" scoped>
.room {
  padding-top: 50px;
  padding-bottom: 60px;
  min-height: 100vh;
  box-sizing: border-box;
  background-color: var(--cp-bg);
  .van-pull-refresh {
    width: 100%;
    min-height: calc(100vh - 150px);
  }
}
</style>
